#include "arpa/inet.h"
#include "netinet/in.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/socket.h"
#include "sys/types.h"
#include "time.h"
#include "unistd.h"

#define PORTNUM 13000

#define oops(m) \
  {             \
    perror(m);  \
    exit(1);    \
  }

int main(int ac, char *av[]) {
  // step 1: ask kernel for a socket
  int sock_id = socket(PF_INET, SOCK_STREAM, 0);
  if (sock_id == -1) {
    oops("socket");
  }

  // step 2: bind address to socket. Address is host, port
  struct sockaddr_in saddr;
  memset((void *)&saddr, 0, sizeof(saddr));
  const char *ip = av[1];
  saddr.sin_addr.s_addr = inet_addr(ip);
  saddr.sin_port = htons(PORTNUM);
  saddr.sin_family = AF_INET;

  if (bind(sock_id, (struct sockaddr *)&saddr, sizeof(saddr)) != 0) {
    oops("bind");
  }

  // step 3: allow incoming calls with Qsize=1 on socket
  if (listen(sock_id, 1) != 0) {
    oops("listen");
  }

  // main loop: accept(), write(), close()
  while (1) {
    int sock_fd = accept(sock_id, NULL, NULL);
    if (sock_fd == -1) {
      oops("accept");
    }
    time_t now = time(NULL);
    char *cp = ctime(&now);
    printf("server: %s", cp);
    if (write(sock_fd, cp, strlen(cp)) == -1) {
      oops("write");
    }
    close(sock_fd);
  }
  return 0;
}